/**
 * 广寒宫
 * 网址:www.guanghangong.xyz
 */
package org.moon.framework.autoconfigure.cors;

import org.moon.framework.autoconfigure.cors.prop.SpringMvcCorsProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import javax.servlet.Filter;
import java.util.Optional;

/**
 * 跨域处理
 * @author moon
 */
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnProperty(value = "moon.cors.enabled", matchIfMissing = false)
@EnableConfigurationProperties(SpringMvcCorsProperties.class)
public class SpringMvcCorsAutoConfiguration {

    @Bean
    public Filter corsFilter(SpringMvcCorsProperties springMvcCorsProperties) {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration(Optional.ofNullable(springMvcCorsProperties.getPath())
                .orElse("/**"), buildConfig(springMvcCorsProperties));
        return new CorsFilter(source);
    }

    private CorsConfiguration buildConfig(SpringMvcCorsProperties springMvcCorsProperties) {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        Optional.ofNullable(springMvcCorsProperties.getAllowOrigins())
                .ifPresent(origins -> origins.forEach(corsConfiguration::addAllowedOriginPattern));
        Optional.ofNullable(springMvcCorsProperties.getAllowHeaders())
                .ifPresent(headers -> headers.forEach(corsConfiguration::addAllowedHeader));
        Optional.ofNullable(springMvcCorsProperties.getAllowMethods())
                .ifPresent(methods -> methods.forEach(corsConfiguration::addAllowedMethod));
        Optional.ofNullable(springMvcCorsProperties.getAllowExposeHeaders())
                .ifPresent(headers -> headers.forEach(corsConfiguration::addExposedHeader));
        corsConfiguration.setAllowCredentials(true);
        return corsConfiguration;
    }
}